P1D.7: COMTRADE workstation synchronous cursor and instant PRI/SEC - #300
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 832165348c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| else | ||
| { | ||
| QueueP1D4LiveAnalysisScrub(isFinal: true); |
There was a problem hiding this comment.
Apply the selected representation to analysis magnitudes
When a record declares a transformer ratio and the operator selects Primary while Phasor or Harmonics is active, this branch merely reruns the same unscaled analysis: ReadPhasorVectors passes the raw MagnitudeRms, and the harmonic overview passes raw DC, fundamental, dominant, and bin magnitudes, while neither native API accepts the selected representation. The displayed absolute values therefore remain in the recorded representation even though Primary is selected; apply P1D5DisplayScale to every absolute analysis magnitude while leaving angles and percentages unchanged.
AGENTS.md reference: AGENTS.md:L153-L153
Useful? React with 👍 / 👎.
| StopP1D5LocusCursorPump(); | ||
| _p1d5LocusCursorDirty = false; | ||
|
|
||
| _p1d5LocusSession?.Dispose(); |
There was a problem hiding this comment.
Avoid disposing the locus session on the UI thread
When the operator leaves Locus while BuildP1D5LocusSeries is executing in Task.Run, the native read holds the session's _sync lock for a full-record locus call, and this synchronous Dispose() on the UI thread waits for that same lock. On a large record, switching modes can therefore freeze the window until the native scan returns despite the preceding cancellation; defer disposal until the worker has completed or otherwise make shutdown asynchronous.
AGENTS.md reference: AGENTS.md:L78-L90
Useful? React with 👍 / 👎.
| if (relative % outputStride != 0 && relative + 1 != range.FrameCount) | ||
| continue; | ||
|
|
||
| values.Add(finiteCount > 0 ? Math.Sqrt(Math.Max(0.0, sumSquares / finiteCount)) * scale : 0.0); |
There was a problem hiding this comment.
Pre-roll RMS calculations at viewport boundaries
When a zoomed or panned viewport starts after frame 0, BuildBounded initializes an empty RMS window at startFrame and immediately publishes values, so every output during the first nominal cycle is calculated from only the post-boundary subset of the cycle. The same waveform can consequently show different leading RMS values solely because the viewport boundary moved; read one cycle of preceding samples or mark/suppress the incomplete leading window.
AGENTS.md reference: AGENTS.md:L11-L16
Useful? React with 👍 / 👎.
| if (_p1d5WaveformTraceMode == mode || _p1d5PresentationRefreshRunning) | ||
| return; |
There was a problem hiding this comment.
Preserve the final trace-mode selection during reloads
On a large record, clicking RMS starts an asynchronous waveform reload and leaves the controls enabled; if the operator clicks Instant before that reload completes, this guard discards the newer request because _p1d5PresentationRefreshRunning is true, leaving RMS selected despite the final interaction. Queue or coalesce the requested mode so the last click is committed after the in-flight reload finishes.
AGENTS.md reference: AGENTS.md:L96-L106
Useful? React with 👍 / 👎.
| DisturbanceView.SetViewWindow(previousView.StartMilliseconds, previousView.EndMilliseconds); | ||
| } | ||
|
|
||
| DigitalEventGrid.ItemsSource = BuildDigitalEventRows(result.Tracks, triggerMs); |
There was a problem hiding this comment.
Use the effective trigger for digital event rows
For legacy COMTRADE records whose first DAT timestamp is nonzero, triggerMs is an offset from CFG StartTime while each event's absolute time is still in the raw DAT coordinate system, so this constructs event times shifted by the first timestamp. The deferred normalizer does not reliably repair this: it is only queued on NavigationChanged, which the shell suppresses when a full-record signal reload keeps the same bounds. Pass DisturbanceView.EffectiveTriggerMilliseconds when constructing the rows so timestamps remain correct after such reloads.
AGENTS.md reference: AGENTS.md:L153-L153
Useful? React with 👍 / 👎.
Final status — MERGED
COMTRADE P1D.7 was field-accepted and integrated to
mainas consolidated squash commitc3e2ac3ef6e6a3a49f47c5155a0ba4a7c00bcb6b.This PR is the final integrated result of the P1D COMTRADE stack. Obsolete lower stacked PRs (#295, #297, #298, #299) were closed as superseded rather than merged again.
Accepted scope
Native engine
ArdIrec PR #41 was merged before this application integration. ARSAS remains pinned to the exact field-qualified bridge commit
7dbc7149db668126a493ce338264363a6ec5ec00, now part of ArdIrecmain, until a separately qualified dependency update is accepted.Qualification before merge
Merge-prep head passed:
The merged
maincommit also passed post-merge Build #2572 and Installer #894.Parallel workstreams
FAT/P8 work remains independent and field-gated. Future integration must follow
docs/WORKSTREAM_COORDINATION.mdand the rootAGENTS.md: integrate latestmain, preserve accepted behavior from both workstreams, then qualify the exact combined head before merge.No further COMTRADE merge action is required from this PR.